/**
 * 使用uniapp的框架做H5时，可以引用
 *
 * 使用方法：在template.h5.html中引入
 <script src="/public/transcode.js" type="text/javascript"></script>
 <script src="/public/ossUploadJs/myOssSdk.js" type="text/javascript" charset="utf-8"></script>
 <script src="/public/ossUploadJs/uploadAliyunUniapp.js" type="text/javascript" charset="utf-8"></script>

 eg: 上传视频的时候使用
GlobalUploadFile(res.tempFilePath,'video', (videoRes) => {
    alert()
}, (err) => {
    uni.showModal({
        title: '提示',
        content: '文件上传失败',
        success (res) {
            console.log(err)
        }
    })
    uni.hideLoading();
});
 */


const Base64_2 = new Base64();

function randomWord(randomFlag, min, max) {
    let str = "", range = min,
        arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
            'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
            'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
        ];
    // 随机产生
    if (randomFlag) {
        range = Math.round(Math.random() * (max - min)) + min;
    }
    for (let i = 0; i < range; i++) {
        let pos = Math.round(Math.random() * (arr.length - 1));
        str += arr[pos];
    }
    return str;
}

function timestampToDate(timestamp) {
    if ((timestamp + '').length < 13) {
        timestamp = timestamp * 1000
    }
    var date = new Date(timestamp);//时间戳为10位需*1000，时间戳为13位的话不需乘1000
    var Y = date.getFullYear();
    var M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1);
    var D = (date.getDate() < 10 ? '0' + date.getDate() : date.getDate());
    return Y + M + D;
}

const OssUploadConfig = function (callback) {
    let random = randomWord(false, 16);
    let transcode = new TransCode();
    let postData = {
        client_name: random
    }; //发送的信息
    let headers = transcode.headers(1); //headers参数
    // let url = "http://review.360tianma.com/api/Upload/getUploadConfig";
    let url = window.location.origin + "/api/Upload/getUploadConfig";

    uni.request({
        url: url,
        method: "post",
        header: {
            'Content-Type': 'application/x-www-form-urlencoded',
            ...headers
        },
        data: {
            tm_encrypt_data: transcode.encrypt(postData)
        },
        success: (result) => {

            if (result.data.code == 200) {
                let data = result.data.data;
                let env = transcode.decrypt(data);
                // console.log(env)
                callback({status: 'success', statusCode: 200, code: 200, data: env});
            } else {
                callback({status: 'success', statusCode: 200, code: result.data.code, msg: result.data.msg});
            }
        },
        fail: (err) => {
            callback({status: 'fail', statusCode: 500, data: err});
        }
    });

    // $.ajax({
    //     url: url,
    //     data: {
    //         tm_encrypt_data: transcode.encrypt(postData)
    //     },
    //     type: 'post',
    //     headers: {
    //         'Content-Type': 'application/x-www-form-urlencoded',
    //         ...headers
    //     },
    //     success: function (result) {
    //         if (result.code == 200) {
    //             let data = result.data;
    //             let env = transcode.decrypt(data);
    //             callback({ status: 'success', statusCode: 200, code: 200, data: env });
    //         } else {
    //             callback({ status: 'success', statusCode: 200, code: result.code, msg: result.msg });
    //         }
    //     },
    //     error: function (err) {
    //         callback({ status: 'fail', statusCode: 500, data: err });
    //     }
    // });
}

const OssUploadFormData = function (env, file, fileType) {
    let random = randomWord(false, 16);
    const aliyunFileKey = timestampToDate(new Date().getTime()) + '/' + random + '_' + (new Date().getTime()) + getFileType(file.name);
    // console.log(aliyunFileKey)
    const aliyunServerURL = 'https://' + env.bucket + '.' + env.endpoint;
    const accessid = env.sts_info.AccessKeyId;
    const policyBase64 = getPolicyBase64(env.sts_info.Expiration);
    const signature = getSignature(policyBase64, env.sts_info.AccessKeySecret);

    let formData = new FormData();
    formData.append('key', aliyunFileKey)
    formData.append('OSSAccessKeyId', accessid)
    formData.append('policy', policyBase64)
    formData.append('Signature', signature)
    formData.append('x-oss-security-token', env.sts_info.SecurityToken)
    formData.append('success_action_status', 200)
    // formData.append('file', file)

}

/**
 * 根据文件名称获取文件后缀
 * @param fileName
 */
function getFileType(fileName) {
    var index1 = fileName.lastIndexOf(".");
    var index2 = fileName.length;
    var type = fileName.substring(index1, index2);
    return type;
}

/**
 * @param {Object} env   后台返回得OSS相关配置
 * @param {Object} filePath   选择文件后返回的临时文件路径
 * @param {String} fileType   文件分类   image  or  video or audio
 * @param {String} cdn   cdn的域名，如果cdn存在，就返回cdn的图片链接，没有就拼接OSS
 * @param {Object} successCB 上传成功的回调函数
 * @param {Object} errorCB    上传失败的回调函数
 */
function uploadFileToOss(env, filePath, fileType, cdn, successCB, errorCB) {
    let random = randomWord(false, 16);
    const aliyunFileKey = timestampToDate(new Date().getTime()) + '/' + random + '_' + (new Date().getTime()) + getFileType(filePath);
    // console.log(aliyunFileKey)
    const aliyunServerURL = 'https://' + env.bucket + '.' + env.endpoint;
    const accessid = env.sts_info.AccessKeyId;
    const policyBase64 = getPolicyBase64(env.sts_info.Expiration);
    const signature = getSignature(policyBase64, env.sts_info.AccessKeySecret);

    // let formData = new FormData();
    // formData.append('key', aliyunFileKey)
    // formData.append('OSSAccessKeyId', accessid)
    // formData.append('policy', policyBase64)
    // formData.append('Signature', signature)
    // formData.append('x-oss-security-token', env.sts_info.SecurityToken)
    // formData.append('success_action_status', 200)
    // formData.append('file', file)


    uni.uploadFile({
        url: aliyunServerURL, //仅为示例，非真实的接口地址
        filePath: filePath,
        name: 'file',
        formData: {
            'key': aliyunFileKey,
            'OSSAccessKeyId': accessid,
            'policy': policyBase64,
            'Signature': signature,
            'x-oss-security-token': env.sts_info.SecurityToken,
            'success_action_status': '200',
        },
        success: function (res) {
            if (res.statusCode != 200) {
                errorCB({status: 'fail', data: JSON.stringify(res), statusCode: res.statusCode})
                return;
            }
            let thumb = '', path = '', base = cdn + '/' + aliyunFileKey;
            if (!cdn) {
                base = aliyunServerURL + '/' + aliyunFileKey;
            }
            if (env.upload_type == 'oss' && fileType === 'video') {
                thumb = base + '?x-oss-process=video/snapshot,t_800,m_fast';
                path = base;
            }
            if (env.upload_type == 'oss' && fileType === 'image') {
                // path = base + '?x-oss-process=image/quality,Q_60'
                path = base;
            }
            successCB({status: 'success', statusCode: 200, code: 200, path: path, thumb: thumb});
        },
        fail: function (err) {
            errorCB({status: 'fail', data: err, statusCode: 500})
        },
    })


    // $.ajax({
    //     url: aliyunServerURL,
    //     data: formData,
    //     type: 'post',
    //     processData: false,
    //     //关键是要设置contentType 为false，不然发出的请求头 没有boundary
    //     //该参数是让jQuery去判断contentType
    //     contentType: false,
    //     success: function (res) {
    //         let thumb = '';
    //         if (env.upload_type == 'oss' && fileType === 'video') {
    //             thumb = aliyunServerURL + '/' + aliyunFileKey + '?x-oss-process=video/snapshot,t_800,m_fast'
    //         }
    //         successCB({status: 'success',statusCode: 200, code: 200, path: aliyunServerURL + '/' + aliyunFileKey, thumb: thumb});
    //     },
    //     error: function (err) {
    //         errorCB({
    //             status: 'fail',
    //             data: err,
    //             statusCode: 500
    //         })
    //     },
    // });
}

/**
 * @param {Object} file   要上传的资源的本地路径
 * @param {String} fileType   文件分类   image  or  video   如果是video的话，会在结果返回封面图
 * @param {Object} successCB 上传成功的回调函数
 * @param {Object} errorCB    上传失败的回调函数
 */
const GlobalUploadFile = function (filePath, fileType, successCB, errorCB) {

    OssUploadConfig((data) => {
        if (data.status == 'success') {
            let env = data.data;   //阿里云的相关配置{aliyunServerURL, accessid, accesskey, expiration}

            if (env.upload_type.toLowerCase() == 'oss') {   //oss上传的话
                uploadFileToOss(env, filePath, fileType, env.cdn || '', (res) => {
                    successCB(res);
                }, (error) => {
                    errorCB(error)
                })
            } else {
                uploadFileToLocal(filePath, (res) => {
                    successCB(res);
                }, (error) => {
                    errorCB(error)
                })
            }
        } else {
            errorCB(data)
        }
    })
}

function uploadFileToLocal(filePath, successCB, errorCB) {
    // let url = "http://review.360tianma.com/api/Upload/fileUpload?upload_type=local";
    let url = window.location.origin + "/api/Upload/fileUpload?upload_type=local";
    uni.uploadFile({
        url: url, //仅为示例，非真实的接口地址
        filePath: filePath,
        name: 'file',
        formData: {},
        success: function (res) {
            if (isJSON_test(res.data)) {
                res.data = JSON.parse(res.data)
            }
            if (res.data.code == 200) {
                let thumb = '';
                successCB({status: 'success', statusCode: 200, code: 200, path: res.data.data.url, thumb: thumb});
            } else {
                errorCB({status: 'fail', msg: res.msg, code: res.code, statusCode: 200})
            }
        },
        fail: function (err) {
            errorCB({status: 'fail', data: err, statusCode: 500})
        },
    })

    // let formData = new FormData();
    // formData.append('file', file)
    // $.ajax({
    //     url:  url,
    //     data: formData,
    //     type: 'post',
    //     processData: false,
    //     //关键是要设置contentType 为false，不然发出的请求头 没有boundary
    //     //该参数是让jQuery去判断contentType
    //     contentType: false,
    //     success: function (res) {
    //         if(res.code == 200) {
    //             let thumb = '';
    //             successCB({status: 'success',statusCode: 200, code: 200, path: res.data.url, thumb: thumb});
    //         }else {
    //             errorCB({
    //                 status: 'fail',
    //                 msg: res.msg,
    //                 code: res.code,
    //                 statusCode: 200
    //             })
    //         }
    //     },
    //     error: function (err) {
    //         errorCB({
    //             status: 'fail',
    //             statusCode: 500
    //         })
    //     },
    // });
}

function getPolicyBase64(expiration) {
    const policyText = {
        "expiration": expiration, //设置该Policy的失效时间，超过这个失效时间之后，就没有办法通过这个policy上传文件了 指定了Post请求必须发生在2020年01月01日12点之前("2020-01-01T12:00:00.000Z")。
        "conditions": [
            ["content-length-range", 0, 2000 * 1024 * 1024] // 设置上传文件的大小限制,1048576000=1000mb
        ]
    };
    const policyBase64 = Base64_2.encode(JSON.stringify(policyText));
    return policyBase64;
}

function getSignature(policyBase64, accesskey) {
    const bytes = Crypto.HMAC(Crypto.SHA1, policyBase64, accesskey, {
        asBytes: true
    });
    const signature = Crypto.util.bytesToBase64(bytes);

    return signature;
}

/**
 * @param {Object} str 传入需要验证的字符串
 * 验证字符串是否是JSON字符串
 */
function isJSON_test(str) {
    if (typeof str == 'string') {
        try {
            var obj = JSON.parse(str);
            if (typeof obj == 'object' && obj) {
                return true;
            } else {
                return false;
            }
        } catch (e) {
            return false;
        }
    }
    return false;
}

